package com.cx.base.dao;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Component;

/**
 * 产生数据表字段的映射实体，请注意映射规则。
 * <ul>
 * 	<li>若表字段名包含下划线‘_’，则pojo属性需要将后面的字符转大写且去掉下划线</li>
 *  <li>若表字段名不包含下划线，请将pojo对应的属性名称一律小写</li>
 * </ul>
 * 
 * @author Hungel zou
 * @since 2014年5月13日 下午4:54:46
 */
@Component
public class DBColumnMapper {

	private static Map<String, List<ColumnMapper>> mapper = new HashMap<String, List<ColumnMapper>>();

	/**
	 * 数据库表字段名的分隔符
	 */
	private static final String UNDERLINE = "_";
	
	/**
	 * 获取pojo对应的字段映射
	 * 
	 * @param clazz
	 *            : 指定的pojo实体类，对应于数据表属性
	 * @param needParentField
	 *            ：是否需要父类的属性，目前指取直属父类属性
	 * @return
	 */
	public List<ColumnMapper> getColumnMapper(Class<?> clazz, boolean needParentField) {
		List<ColumnMapper> columnMapperList = mapper.get(clazz.getName());
		if (columnMapperList == null) {
			columnMapperList = generateColumnMapper(clazz, needParentField);
			mapper.put(clazz.getName(), columnMapperList);
		}
		return columnMapperList;
	}
	
	/**
	 * 产生字段映射
	 * 
	 * @param clazz
	 * @param needParentField
	 * @return
	 */
	private List<ColumnMapper> generateColumnMapper(Class<?> clazz, boolean needParentField) {
		List<ColumnMapper> columnMapperList = new ArrayList<ColumnMapper>();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			String fieldName = field.getName();
			if (!"serialVersionUID".equalsIgnoreCase(fieldName)) {
				columnMapperList.add(createColumnMapper(fieldName));
			}
		}
		// 是否需要直属父类属性
		if (needParentField) {
			Class<?> c = clazz.getSuperclass();
			List<ColumnMapper> superCMList = generateColumnMapperBySuperClass(c);
			if (superCMList != null) {
				columnMapperList.addAll(superCMList);
			}
		}
		return columnMapperList;
	}

	/**
	 * 根据父类的属性产生字段映射
	 * 
	 * @param c
	 * @return
	 */
	private List<ColumnMapper> generateColumnMapperBySuperClass(Class<?> c) {
		if (c != null) {
			Field[] f = c.getDeclaredFields();
			if (f != null && f.length > 0) {
				List<ColumnMapper> columnMapperList = new ArrayList<ColumnMapper>();
				for (Field field : f) {
					String fieldName = field.getName();
					if (!"serialVersionUID".equalsIgnoreCase(fieldName)) {
						columnMapperList.add(createColumnMapper(fieldName));
					}
				}
				return columnMapperList;
			}
		}
		return null;
	}
	
	/**
	 * 创建映射实体对象
	 * 
	 * @param fieldName
	 * @return
	 */
	private ColumnMapper createColumnMapper(String fieldName) {
		ColumnMapper columnMapper = new ColumnMapper();
		columnMapper.setFiled(fieldName);
		columnMapper.setColumn(obtainColumn(fieldName));
		return columnMapper;
	}
	
	/**
	 * 字段名称与表字段名称的映射转换
	 * 
	 * @param fieldName
	 * @return
	 */
	protected String obtainColumn(String fieldName) {
		StringBuffer builder = new StringBuffer();
		char[] charArray = fieldName.toCharArray();
		for (int index = 0; index < charArray.length; index++) {
			char ch = charArray[index];
			if (Character.isUpperCase(ch)) {
				if (index == 0) {
					builder.append(Character.toLowerCase(ch));
				} else {
					builder.append(UNDERLINE);
					builder.append(Character.toLowerCase(ch));
				}
			} else {
				builder.append(ch);
			}
		}
		return builder.toString();
	}

}
